include_guard(GLOBAL)

# Guard against using the wrong compiler

if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0)
    message(FATAL_ERROR "Only Clang 9 or newer is supported for C++ code!")
endif()

if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
    message(FATAL_ERROR "Only Clang 9 or newer is supported for C code!")
endif()

# Call this function on any FrameFlow-related target
function(frameflow_setup_target target)
    target_compile_options(${target} PRIVATE
        -Wall
        -Werror
        -Wextra
        -Wpedantic
        -Wshadow
        -Wno-unknown-warning-option
        -Wno-bitwise-instead-of-logical
        -Wno-c++20-designator
        -Wno-unused-command-line-argument
        -fno-rtti
        -Wno-c99-extensions
    )

    target_link_options(${target} PRIVATE
        # Fail when undefined symbols are present at link stage.
        # This can happen if you use some external function from frameflow
        # but forget to link it with the appropriate shared library.
        # Then libframeflow will "silently" depend on that library
        # (won't load without it and will not add it to NEEDED section).
        -Wl,--no-undefined
    )

    set_target_properties(${target} PROPERTIES
        C_STANDARD 11 C_STANDARD_REQUIRED TRUE
        CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE

        C_VISIBILITY_PRESET hidden
        CXX_VISIBILITY_PRESET hidden

        POSITION_INDEPENDENT_CODE ON

        # Remove useless -D`target`_EXPORTS definition by CMake
        DEFINE_SYMBOL ""
    )

    if(WIN32 OR OHOS OR ANDROID)
        # Use LTO for release builds (this is ThinLTO on Clang) except Ubuntu
        if(CMAKE_BUILD_TYPE MATCHES Release)
            # "INTERPROCEDURAL_OPTIMIZATION_RELEASE ON" option works incorrectly
            # with Android NDK build on Linux and OHOS SDK build on Linux
            target_compile_options(${target} PRIVATE "-flto=thin")
        endif()
    endif()

    if(OHOS)
        # to define "__OHOS__" in FrameFlow code
        target_compile_definitions(${target} PRIVATE "__OHOS__")

        # cmake from OHOS SDK generates unused "--gcc-toolchain" compilation argument
        # ignore this warning
        # "-Wno-error=unused-command-line-argument" option prints a lot of warnings
        target_compile_options(${target} PRIVATE "-Qunused-arguments")
    endif()

    if(WIN32)
        target_link_options(${target} PRIVATE
            # Link C++ runtime statically so that the library
            # is not dependent on any MSYS-specific libraries
            -static-libstdc++
        )

        set_target_properties(${target} PROPERTIES
            # "libframeflow.dll" => "frameflow.dll" when building under MSYS toolchain
            SHARED_LIBRARY_PREFIX ""
        )
    endif()
endfunction()
